var simuParams = {},
    currentFlowSizeCDFRule = [],
    currentPacketSizeCDFRule = [],
    currentPacketIntervalCDFRule = [],
    CDFRules = {},
    flows = [];

var flowId = 0,
    flowSizeId = 0,
    packetSizeId = 0,
    packetIntervalId = 0;

function convert(val, unit) {
    val = parseInt(val);

    if (unit == 'KB' || unit == 'ms') {
        val *= 1000;
    } else if (unit == 'MB' || unit == 's') {
        val *= 1000000;
    } else if (unit == 'GB') {
        val *= 1000000000;
    }

    return val;
}

function addNavBarEvent() {
    
    $("header li").click(function() {
        
        // add `active` class for clicked `li`
        $(this)
            .siblings().removeClass('active')
        .end()
            .addClass('active');

        // display the `div` has the className with `a[href]` 
        var className = $(this).children('a').attr('href');
        $("div[id]").css({"display": "none"});
        $(className).css({"display": "block"});
    });
}

function updateFlowSrcDst() {

    var $src = $("#src"),
        $dst = $('#dst');

    for (var i = 1; i <= simuParams.hostNum; i++) {
        if (i !== simuParams.ctrlPos) {
            $('<option value="' + i + '">' + i + '</option>').appendTo($src);
            $('<option value="' + i + '">' + i + '</option>').appendTo($dst);
        }
    }

    if (simuParams.topoLevel == 3) {
        $('<option value="POD">POD</option>').appendTo($('#granularity'));
    }
}

function sendAjaxRequest() {
    
    $.ajax({
        type: "POST",
        url: "/simulation/start",
        data: JSON.stringify({
            "simuParams": simuParams,
            "CDFRules": CDFRules,
            "flows": flows
        }),
        dataType: "json",
        suceess: function (data) {
            console.log("hello world! ajax successed");
        }
    });
}

function addBasicEvent() {

    $("#topoType").change(function () {

        var level = $(this).val();

        if (level == 2) {
            $("div.level2").css({"display": "block"});
            $("div.level3").css({"display": "none"});
        } else {
            $("div.level2").css({"display": "none"});
            $("div.level3").css({"display": "block"});    
        }
    });

    $("#confirm").click(function () {
        
        simuParams = {
            topoLevel: Number($("#topoType").val()),
            pHostNum:  Number($("#phostnum").val()),
            ctrlPos:   Number($("#ctrlpos").val()),
            simuTime:  Number($("#simutime").val()),
            outFile:   Number($("#outfile").val())
        };

        if (simuParams.topoLevel == 2) {
            simuParams.uSwitchNum = Number($("#uswitchnum").val());
            simuParams.lSwitchNum = Number($("#lswitchnum").val());
            simuParams.switchNum = simuParams.uSwitchNum + 
                                   simuParams.lSwitchNum;
            simuParams.hostNum = simuParams.lSwitchNum * 
                                 simuParams.pHostNum;
        } else {
            simuParams.coreSwitchNum = Number($("#coreswitchnum").val());
            simuParams.podNum = Number($("#podnum").val());
            simuParams.pSwitchNum = Number($("#pswitchnum").val());
            simuParams.switchNum = simuParams.coreSwitchNum + 
                                   simuParams.podNum * simuParams.pSwitchNum * 2;
            simuParams.hostNum =  simuParams.podNum * 
                                  simuParams.pSwitchNum *
                                  simuParams.pHostNum; 
        }

        console.log(simuParams);
        updateFlowSrcDst();
    });
}

function addCDFEvent() {

    // add a flow-size CDF distrubtion rule
    $("#addFlowSizeCDFBtn").click(function () {
        
        var $flowSize = $("#flowsize"),
            $cdfValue = $("#flowsizecdfvalue"),
            $flowSizeUnit = $('#flowsizeunit'),
            $tmpTbl = $("#tempflowsizecdf");

        $tmpTbl.css({"display": "block"});
        
        flowSizeId++;
        $("<tr>" + 
            "<td>" + $flowSize.val() + $flowSizeUnit.val() + "</td>" + 
            "<td>" + $cdfValue.val() + "</td>" +
            '<td><span class="glyphicon glyphicon-remove" data-index="' + flowSizeId + '"></span></td>' + 
          "</tr>"
        ).appendTo($tmpTbl.children("tbody"));

        $("#tempflowsizecdf td").last().children('span').click(function (ev) {
            $(this).parent().parent().remove();
            if ($("#tempflowsizecdf td").length == 0) {
                $tmpTbl.hide();
            }
            var id = Number($(this).data('index'));
            for (var idx in flows) {
                if (currentFlowSizeCDFRule[idx].id == id) {
                    break;
                }
            }
            currentFlowSizeCDFRule.splice(idx, 1);
        });

        // Record current CDF distribution
        currentFlowSizeCDFRule.push({
            id: flowSizeId,
            value: convert($flowSize.val(), $flowSizeUnit.val()),
            cdf: $cdfValue.val()
        });

        $flowSize.val("");
        $cdfValue.val("");
    });

    // add a packet-size CDF distrubtion rule
    $("#addPacketSizeCDFBtn").click(function () {
        
        var $packetSize = $("#packetsize"),
            $cdfValue = $("#packetsizecdfvalue"),
            $packetSizeUnit = $('#packetsizeunit'),
            $tmpTbl = $("#temppacketsizecdf");

        $tmpTbl.css({"display": "block"});

        packetSizeId++;
        $("<tr>" + 
            "<td>" + $packetSize.val() + $packetSizeUnit.val() + "</td>" + 
            "<td>" + $cdfValue.val() + "</td>" +
            '<td><span class="glyphicon glyphicon-remove" data-index="' + packetSizeId + '"></span></td>' + 
          "</tr>"
        ).appendTo($tmpTbl.children("tbody"));

        $("#temppacketsizecdf td").last().children('span').click(function (ev) {
            $(this).parent().parent().remove();
            if ($("#temppacketsizecdf td").length == 0) {
                $tmpTbl.hide();
            }
            var id = Number($(this).data('index'));
            for (var idx in flows) {
                if (currentPacketSizeCDFRule[idx].id == id) {
                    break;
                }
            }
            currentPacketSizeCDFRule.splice(idx, 1);
        });

        // Record current CDF distribution
        currentPacketSizeCDFRule.push({
            id: packetSizeId,
            value: convert($packetSize.val(), $packetSizeUnit.val()),
            cdf: $cdfValue.val()
        });

        $packetSize.val("");
        $cdfValue.val("");
    });

    // add a packet-interval CDF distrubtion rule
    $("#addPacketIntervalCDFBtn").click(function () {
        
        var $packetInterval = $("#packetinterval"),
            $cdfValue = $("#packetintervalcdfvalue"),
            $packetIntervalUnit = $('#packetintervalunit'),
            $tmpTbl = $("#temppacketintervalcdf");

        $tmpTbl.css({"display": "block"});
        
        packetIntervalId++;
        $("<tr>" + 
            "<td>" + $packetInterval.val() + $packetIntervalUnit.val() + "</td>" + 
            "<td>" + $cdfValue.val() + "</td>" +
            '<td><span class="glyphicon glyphicon-remove" data-index="' + packetIntervalId + '"></span></td>' + 
          "</tr>"
        ).appendTo($tmpTbl.children("tbody"));

        $("#temppacketintervalcdf td").last().children('span').click(function (ev) {
            $(this).parent().parent().remove();
            if ($("#temppacketintervalcdf td").length == 0) {
                $tmpTbl.hide();
            }
            var id = Number($(this).data('index'));
            for (var idx in flows) {
                if (currentPacketIntervalCDFRule[idx].id == id) {
                    break;
                }
            }
            currentPacketIntervalCDFRule.splice(idx, 1);
        });

        // Record current CDF distribution
        currentPacketIntervalCDFRule.push({
            id: packetIntervalId,
            value: convert($packetInterval.val(), $packetIntervalUnit.val()),
            cdf: $cdfValue.val()
        });

        $packetInterval.val("");
        $cdfValue.val("");
    });

    // display a complete CDF distrubtion
    $("#confirmCDFBtn").click(function () {

        var $tmpFlowSizeTbl = $("#tempflowsizecdf"),
            $tmpPacketSizeTbl = $("#temppacketsizecdf"),
            $tmpPacketIntervalTbl = $("#temppacketintervalcdf"),
            $cdfName = $("#cdfname");

        $('<div class="form-group">' + 
            '<div class="cdf-name col-md-offset-2 col-md-4">' + 
                $cdfName.val() + 
                '<p class="glyphicon glyphicon-remove" data-name="' + $cdfName.val() + '"></p>' + 
            '</div>' +
          '</div>' + 
          '<div class="cdf-forms">' + 
            '<div class="form-group">' + 
              '<div class="col-md-offset-2 col-md-4">' +
                '<table class="table table-hover">' + 
                  $tmpFlowSizeTbl.html() + 
                '</table>' + 
              '</div>' +
            '</div>' + 
            '<div class="form-group">' + 
              '<div class="col-md-offset-2 col-md-4">' +
                '<table class="table table-hover">' + 
                  $tmpPacketSizeTbl.html() + 
                '</table>' + 
              '</div>' +
            '</div>' +
            '<div class="form-group">' + 
              '<div class="col-md-offset-2 col-md-4">' +
                '<table class="table table-hover">' + 
                  $tmpPacketIntervalTbl.html() + 
                '</table>' + 
              '</div>' +
            '</div>' +
          '</div>'
        ).appendTo($("#cdf form").last());

        $("#cdf form span").hide();
        
        $(".cdf-name").click(function () {
            if ($(this).parent().next().css("display") == 'block') {
                $(this).parent().next().hide();
            } else {
                $(this).parent().next().show();
            }
        });

        $(".cdf-name p").click(function () {
            delete CDFRules[$(this).data("name")];
            $(this).parent().parent().next().remove();
            $(this).parent().parent().remove();
        });

        // set CDF name as a flow trace option
        $('<option value="' + $cdfName.val() + '">' + $cdfName.val() + '</option>')
            .appendTo($('#flowtrace'));

        // record CDF rule
        CDFRules[$cdfName.val()] = {
            flowSize: currentFlowSizeCDFRule,
            packetSize: currentPacketSizeCDFRule,
            packetInterval: currentPacketIntervalCDFRule
        };
        currentFlowSizeCDFRule = [];
        currentPacketSizeCDFRule = [];
        currentPacketIntervalCDFRule = [];

        // reset 
        $tmpFlowSizeTbl.children('tbody').html("");
        $tmpFlowSizeTbl.css({"display": "none"});
        $tmpPacketSizeTbl.children('tbody').html("");
        $tmpPacketSizeTbl.css({"display": "none"});
        $tmpPacketIntervalTbl.children('tbody').html("");
        $tmpPacketIntervalTbl.css({"display": "none"});
        $cdfName.val("");
    });
}

function addFlowEvent() {

    $("#addflow").click(function () {

        var $granularity = $("#granularity"),
            $src = $("#src"),
            $dst = $("#dst"),
            $protoType = $("#prototype"),
            $flowNum = $("#flownum"),
            $flowTrace = $("#flowtrace"),
            $flowTbl = $("#flowstats");

        // display in HTML
        $flowTbl.css({"display": "block"});
        flowId++;
        $("<tr>" + 
            "<td>" + $granularity.val() + "</td>" + 
            "<td>" + $src.val() + "</td>" +
            "<td>" + $dst.val() + "</td>" +
            "<td>" + $protoType.val() + "</td>" +
            "<td>" + $flowNum.val() + "</td>" +
            "<td>" + $flowTrace.val() + "</td>" +
            '<td><span class="glyphicon glyphicon-remove" data-index="' + flowId + '"></td>' + 
          "</tr>"
        ).appendTo($flowTbl.children("tbody"));

        $("#flowstats td").last().children('span').click(function (ev) {
            $(this).parent().parent().remove();
            if ($("#flowstats td").length == 0) {
                $flowTbl.hide();
            }
            var id = Number($(this).data('index'));
            for (var idx in flows) {
                if (flows[idx].id == id) {
                    break;
                }
            }
            flows.splice(idx, 1);
        });

        // record flows
        flows.push({
            id: flowId,
            granularity: $granularity.val(),
            src: $src.val(),
            dst: $dst.val(),
            proto: $protoType.val(),
            num: $flowNum.val(),
            trace: $flowTrace.val()
        });

        $granularity.val("主机");
        $src.val($src.children().first().val());
        $dst.val($src.children().first().val());
        $protoType.val("HTTP");
        $flowNum.val("");
        $flowTrace.val("真实Trace数据");
    });
        
    $("#startSimulation").click(function() {
        sendAjaxRequest();
    });
}

$(function () {

    addNavBarEvent();
    addBasicEvent();
    addCDFEvent();
    addFlowEvent();

});
